#ifndef _KOV_H_
#define _KOV_H_

// declaration of structures used in KOV algorithm implementation

#include "..\common\Attribute.h"
#include "..\common\AttributeSet.h"
#include "..\common\Object.h"
#include "..\common\ObjectSet.h"
#include "..\common\OAPair.h"
#include "..\common\FormalContext.h"
#include "..\common\DataStructure.h"
#include "..\common\DataSetLoader.h"
#include <time.h>
#include <iostream>
#include <fstream>
typedef std:: vector<AttributeSet> DeltaClosure;
// central data structure maintaining data loaded from external data source and
// reference pointers to speed up search operations
extern DataStructure data;
// special version of Closure for empty sets
void ClosureForEmptySet(const AttributeSet &all_attrs, OAPair &oa_pair, FormalContext &local_fc);
// closure computes a closure of OAPair element in local formal context
// represented by local_fc object
void Closure(const AttributeSet &all_attrs, OAPair &oa_pair, FormalContext &local_fc);
// sort_f is a sort function that compares two OAPair elements and returns true
// iff e1 is less or equal than e2, false conversely
void Order(FormalContext &local_fc, bool (*sort_f)(const OAPair &e1, const OAPair &e2) = NULL);
// determine local context for the first iteration of KOV algorithm, i.e. 
// w/o considering the minimal support
FormalContext* LocalContext(const OAPair &oa, const FormalContext * const P);
// determine local context for the next iterations of KOV algorithm (KOV-Extend), i.e. 
// considering the minimal support and the delta closure
FormalContext* LocalContextMinSup(const OAPair &oa, DeltaClosure deltaClosure, const FormalContext * const P, unsigned int minSup);

void SaveOA(std::ofstream *fc, OAPair &oa, bool asChar);
void PrintOA(OAPair &oa);
void Kov(DataStructure *ds, std::ofstream *fc, unsigned int minSup, unsigned int* counter, bool asChar, bool (*sort_f)(const OAPair &e1, const OAPair &e2) = NULL);
void KovExtend(AttributeSet *allAttributes, FormalContext &p, unsigned int minSup, std::ofstream *fc, AttributeSet* processedSets, unsigned int* counter, bool asChar, bool (*sort_f)(const OAPair &e1, const OAPair &e2) = NULL);
DeltaClosure ClosureDelta(const OAPair &pair, const FormalContext *p);

#endif